import { isNullOrUnDef, isEmpty } from '/@/utils/is';
import { cloneDeep } from 'lodash-es';
import { Rule } from '/@/components/Form';
import { getModelInstanceInfoApi } from '/@/api/config-center/model-design';

/**
 * @description 表单字段校验
 */

type Trigger = 'blur' | 'change' | ['change', 'blur'];

interface ArrayItem {
  trigger?: Trigger;
  message?: string;
  schema?: Indexable;
}

export const verify = {
  requiredInput: (typeId = 1, message = '', type?: any, trigger?: any, required = true) => {
    let data: any = { required, message: `${typeId === 1 ? '请输入' : '请选择'}${message}` };
    if (type) data = { ...data, type };
    if (trigger) data = { ...data, trigger };
    if (!required) data = { required: false };
    return data;
  },
  // 子表组件数组子项中的值必须有数据
  requireSubTableArrayItem({ schema, trigger = 'change', message }: ArrayItem = {}): Rule {
    return {
      required: schema?.required,
      validator: async (_, values) => {
        const { modelId, tableColumn, operationType } = schema?.componentProps?.config;

        if (!tableColumn) return Promise.resolve();

        if (schema?.required && (!values || !values.length)) {
          const defMsg = '请添加' + schema.label;
          return Promise.reject(message || defMsg);
        }
        // 弹框类型不需要再校验子项
        if (operationType === 'dialog') return Promise.resolve();

        const { formDesignInfo = {} } = await getModelInstanceInfoApi(modelId);

        formDesignInfo.schemas.forEach((el) => {
          const ret = tableColumn.find((col) => col.field === el.field);
          if (ret) {
            ret.required = el.updateType === 2;
          }
        });

        const reqItems = tableColumn
          .filter((el) => el.required)
          .map(({ field, label }) => ({ field, label }));
        // 有必填项需校验

        if (reqItems) {
          const arr = cloneDeep(values || []);
          const emptyItems = arr.filter((el, idx) => {
            el.__idx = idx;

            // 过滤出空值
            return reqItems.some(({ field }) => isNullOrUnDef(el[field]) || isEmpty(el[field]));
          });

          // 有空值的项
          const emptyItemErrorTexts = emptyItems.map((el) => {
            // 整理校验信息
            const res = reqItems
              .filter(({ field }) => {
                return isNullOrUnDef(el[field]) || isEmpty(el[field]);
              })
              .map(({ label }, idx) => {
                const prefix = idx === 0 ? `第${el.__idx + 1}行有未填写字段：` : '';
                return `${prefix}${label}`;
              });

            return res.join();
          });

          if (emptyItemErrorTexts.length) {
            return Promise.reject(emptyItemErrorTexts[0]);
          }
        }

        return Promise.resolve();
      },
      trigger,
      type: 'string',
    };
  },
  enNumber: {
    value: /^[a-z0-9]+$/i,
    label: '仅支持英文和整数',
  },

  // 纯数字
  pureNumber: {
    value: /^[0-9]*$/,
    label: '请输正整数',
  },
  number: {
    value: /^(-)?\d+(\.\d+)?$/,
    label: '仅支持数值',
  },

  // 1-9数字
  number1_9: {
    value: /^[1-9]$/,
    label: '仅支持1-9的整数',
  },
  // 1-31
  number1_31: {
    value: /^([1-9]|[1-2]\d|3[0-1])$/,
    label: '仅支持1-31的整数',
  },
  // 1-99
  number1_99: {
    value: /^(([0-9][1-9])|([1-9][0-9])|[1-9])$/,
    label: '仅支持1-99的整数',
  },
  // 1-9999
  number1_9999: {
    value: /^(1|([1-9]\d{0,3}))$/,
    label: '仅支持1-9999的整数',
  },
  // 1-99999999
  number1_99999999: {
    value: /^(1|([1-9]\d{0,7}))$/,
    label: '大于0小于100000000',
  },
  // 大于0小于1,允许保留2位小数
  float0_1: {
    value: /^0\.[0-9]{1,2}$|^0{1}$|^1{1}$|^1\.[0]{1,2}$/,
    label: '仅支持0-1的两位小数',
  },
  // 0-99之间,支持两位小数
  float0_99: {
    value: /^([1-9]\d{0,1}$)|(^[0-9]{1,2}\.[0-9]{1,2}$)$/,
    label: '仅支持0-99的两位小数',
  },
  // 0-99之间,支持三位小数
  float0_99_3: {
    value: /^([1-9]\d{0,1}$)|(^[0-9]{1,2}\.[0-9]{1,3}$)$/,
    label: '仅支持0-99的三位小数',
  },
  // 0-99之间包含0,支持三位小数
  float0_0_99_3: {
    value: /^0|([1-9]\d{0,1}$)|(^[0-9]{1,2}\.[0-9]{1,3}$)$/,
    label: '大于等于0小于100,支持三位小数',
  },
  // 0-100之间,支持两位小数
  float0_100: {
    value: /^([1-9]\d{0,1}$)|(^[0-9]{1,2}\.[0-9]{1,2}$)|100$/,
    label: '大于0小于等于100,支持两位小数',
  },
  // 大于0的数,支持两位小数
  float0_infinity: {
    value: /(^[1-9](\d+)?(\.\d{1,2})?$)|(^\d\.\d{1,2}$)/,
    label: '仅支持大于0的两位小数',
  },
  float0_infinity_3: {
    value: /(^[1-9](\d+)?(\.\d{1,3})?$)|(^\d\.\d{1,3}$)/,
    label: '仅支持大于0的三位小数',
  },
  // 手机号
  mobile: {
    // value: /^1\d{10}$/,
    value: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/,
    label: '请输入正确的手机号',
  },
  email: {
    value: /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/,
    label: '请输入正确的邮箱',
  },
  // 身份证
  iDCard: {
    value: /^(\d{18}|\d{15}|\d{17}x)$/,
    label: '仅支持身份证号',
  },
  // 中文
  zh: {
    value: /^[\u4e00-\u9fa5],{0,}$/,
    label: '仅支持中文',
  },
  //包含中文及中文特殊字符
  includesZh: {
    value: /[^\x00-\xff]/gi,
    label: '仅支持中文及中文特殊字符',
  },
  // 大小写字母、数字、-
  upperAndLowerNum: {
    value: /^[a-zA-Z0-9\-]+$/,
    label: '仅支持大小写字母、数字、-',
  },
};
